# encoding: utf-8
"""
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    created by lane.chang on '17/10/2024'
    comment: 自定义页面
"""
from fastapi import APIRouter, Request, Body, Query

from config import Config
from project.core.function import json_response
from project.lib.decorator import api_common, exec_duration
from project.model.basic import SubmitInfo
from project.model.database.basic import Component
from project.model.database.flow import FlowPage, FlowProcess, FlowRole
from project.model.database.record import FlowRecord, FlowRecordLog
from project.service.record import RecordService
from project.middleware.jpush import JPush
from project.model.database.cariabot import DeviceJpush


page_router = APIRouter(prefix='/u', tags=['user.page'])


@page_router.get('/flow/page/list', summary='页面列表')
@api_common(doc_replace=(('{0}', Config.ENV_DOC_FIX),))
@exec_duration(add_return=True)
async def get_flow_page_list(request: Request,
                             flow_record_id: int = Query(..., title='服务记录id'),
                             flow_role_id: int = Query(..., title='流程角色id'), session=None):
    """
    **desc**: 角色页面列表

    **url**: http(s)://{0}.udicaria.com/u/flow/page/list

    **method**: GET

    **params**:

        <query>:
            flow_record_id: 服务记录id
            flow_role_id: 流程角色id

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data: [
                {
                    page_type: 页面类型
                    flow_id: 服务流程id
                    flow_code: 服务流程编号
                    flow_role_id: 流程角色id
                    flow_process_id: 服务流程状态id
                    component_id: 组件id
                    component: 组件信息
                    title: 组件标题
                    content: 组件文案
                    remark: 备注信息
                    rate: 组件比例
                    style: 组件样式
                    items: 组件显示的值列表
                    to_flow_process_id: 目标服务流程状态id
                    rank: 排序
                    is_enable: 是否激活 True/false 默认 true
                }
            ]
            exec_time: 接口后端处理时长
        }
    """
    flow_record = await FlowRecord.fetch_one(session, wheres=(FlowRecord.id == flow_record_id))
    if not flow_record:
        return json_response(data=[])

    data = await FlowPage.fetch_all(session, wheres=(FlowPage.flow_role_id == flow_role_id, ~FlowPage.is_deleted), orders=(FlowPage.rank,))

    # 组件信息
    component_ids = [v.component_id for v in data]
    components = await Component.fetch_all(session, wheres=(Component.id.in_(component_ids)))
    component_map = {v.id: v for v in components}

    # 服务记录状态信息
    flow_process = await FlowProcess.fetch_one(session, wheres=(FlowProcess.id == flow_record.flow_process_id))

    # 组件绑定的工单状态信息
    flow_process_ids = [v.flow_process_id for v in data]
    flow_processes = await FlowProcess.fetch_all(session, wheres=(FlowProcess.id.in_(flow_process_ids)))
    flow_process_map = {v.id: v for v in flow_processes}

    items = []
    for v in data:
        d = v.dict()
        component = component_map.get(v.component_id)
        d['component'] = component.dict() if component else {}

        is_enable = True
        _flow_process = flow_process_map.get(v.flow_process_id)
        if _flow_process and flow_process and _flow_process.rank <= flow_process.rank:
            is_enable = False
        d['is_enable'] = is_enable

        items.append(d)

    return json_response(data=items)


@page_router.get('/flow/page/detail', summary='页面详情')
@api_common(doc_replace=(('{0}', Config.ENV_DOC_FIX),))
@exec_duration(add_return=True)
async def get_flow_page_detail(request: Request,
                               flow_record_id: int = Query(..., title='服务记录id'),
                               flow_role_id: int = Query(..., title='流程角色id'),
                               session=None):
    """
    **desc**: 角色页面详情

    **url**: http(s)://{0}.udicaria.com/u/flow/page/detail

    **method**: GET

    **params**:

        <query>:
            flow_record_id: 服务记录id
            flow_role_id: 流程角色id

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data: [
                {
                    page_type: 页面类型
                    flow_id: 服务流程id
                    flow_code: 服务流程编号
                    flow_role_id: 流程角色id
                    flow_process_id: 服务流程状态id
                    component_id: 组件id
                    component: 组件信息
                    title: 组件标题
                    content: 组件文案
                    remark: 备注信息
                    rate: 组件比例
                    style: 组件样式
                    items: 组件显示的值列表
                    to_flow_process_id: 目标服务流程状态id
                    rank: 排序
                }
            ]
            exec_time: 接口后端处理时长
        }
    """
    flow_record = await FlowRecord.fetch_one(session, wheres=(FlowRecord.id == flow_record_id))
    if not flow_record:
        return json_response(data={})

    data = await FlowPage.fetch_all(session, wheres=(FlowPage.flow_role_id == flow_role_id, FlowPage.flow_process_id == flow_record.flow_process_id, ~FlowPage.is_deleted), orders=(FlowPage.rank,))

    # 组件信息
    component_ids = [v.component_id for v in data]
    components = await Component.fetch_all(session, wheres=(Component.id.in_(component_ids)))
    component_map = {v.id: v for v in components}

    items = []
    for v in data:
        d = v.dict()
        component = component_map.get(v.component_id)
        d['component'] = component.dict() if component else {}
        items.append(d)

    return json_response(data=items)


@page_router.get('/flow/process/list', summary='流程状态列表')
@api_common(doc_replace=(('{0}', Config.ENV_DOC_FIX),))
@exec_duration(add_return=True)
async def get_flow_process_list(request: Request, flow_record_id: int = Query(..., title='服务记录id'), session=None):
    """
    **desc**: 服务流程状态列表

    **url**: http(s)://{0}.udicaria.com/u/flow/process/list

    **method**: GET

        <body>:
            flow_record_id: 服务流程id

    **params**:

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data: [
                {
                    name: 流程状态名称
                    flow_id: 所属服务流程id
                    flow_code: 所属服务流程编号
                    is_past: 状态是否已经过(true/false) 默认false
                    past_time: 工单流转时的时间
                    rank: 流程排序
                    remark: 备注信息
                }
            ]
            exec_time: 接口后端处理时长
        }
    """
    flow_record = await FlowRecord.fetch_one(session, wheres=(FlowRecord.id == flow_record_id))
    if not flow_record:
        return json_response(data=[])
    flow_record_logs = await FlowRecordLog.fetch_all(session, wheres=(FlowRecordLog.flow_record_id == flow_record_id))
    past_time_map = {v.flow_process_id: v.create_time for v in flow_record_logs if v.flow_process_id}

    data = await FlowProcess.fetch_all(session, wheres=(FlowProcess.flow_id == flow_record.flow_id, ~FlowProcess.is_deleted), orders=(FlowProcess.rank, ))
    items = []

    for flow_process in data:
        d = flow_process.dict()

        past_time = past_time_map.get(flow_process.id)
        d['is_past'] = bool(past_time)
        d['past_time'] = past_time

        items.append(d)

    return json_response(data=items)


@page_router.get('/flow/role/detail', summary='角色详情')
@api_common(doc_replace=(('{0}', Config.ENV_DOC_FIX),))
@exec_duration(add_return=True)
async def get_flow_role_detail(request: Request,
                               id: int = Query(..., title='角色id'),
                               session=None):
    """
    **desc**: 流程角色详情

    **url**: http(s)://{0}.udicaria.com/u/flow/role/detail

    **method**: GET

    **params**:

        <body>:
            id: 角色id

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data: {
                role_type: 角色类型: user(用户)/worker(工作人员)
                name: 角色名称
                phone: 手机号
                flow_role_list: [
                    {
                        flow_id: 流程id
                        role_id: 角色id
                    }
                ] # 相关的所有流程角色
            }
            exec_time: 接口后端处理时长
        }
    """
    flow_role = await FlowRole.fetch_one(session, wheres=(FlowRole.id == id, ~FlowRole.is_deleted))
    if not flow_role:
        return json_response(data={})
    data = flow_role.dict('role_type', 'name', 'phone')

    # 获取手机号绑定的所有流程角色
    flow_role_list = []
    if flow_role.phone:
        role_list = await FlowRole.fetch_all(session, wheres=(FlowRole.phone == flow_role.phone, ~FlowRole.is_deleted))
        flow_role_list = [{'flow_id': v.flow_id, 'role_id': v.id} for v in role_list]
    data['flow_role_list'] = flow_role_list

    return json_response(data=data)


@page_router.post('/flow/page/button/click', summary='流程跳转点击')
@api_common(doc_replace=(('{0}', Config.ENV_DOC_FIX),))
@exec_duration(add_return=True)
async def do_page_button_click(request: Request,
                               flow_record_id: int = Body(..., title='服务记录id'),
                               flow_page_id: int = Body(..., title='服务页面id'),
                               flow_role_id: int = Body(..., title='流程角色id'),
                               submit_list: list[SubmitInfo] = Body('', title='提交信息列表'),
                               session=None):
    """
    **desc**: 按钮点击

    **url**: http(s)://{0}.udicaria.com/u/flow/page/button/click

    **method**: POST

    **params**:

        <body>:
            flow_record_id: 服务记录id
            flow_page_id: 服务页面id
            flow_role_id: 流程角色id
            submit_list: [
                {
                    flow_page_id: 服务页面id
                    submit: 组件提交的信息
                }
            ] # 提交信息列表

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data:
            exec_time: 接口后端处理时长
        }
    """
    flow_record, flow_process = await RecordService.do_page_button_click(session, flow_record_id, flow_page_id, flow_role_id, submit_list)

    # 发送极光推送
    if flow_process.rank <= 1:
        device_jpush = await DeviceJpush.fetch_one(session, wheres=(DeviceJpush.code == flow_record.dev_id))
        if device_jpush:
            title = '播报'
            content = {'action': 'notify', 'response': '你的工单已被接收，管家正在处理。', 'after_broadcast': 'only_broadcast', 'replay_count': 1}
            JPush.send(device_jpush.registration_id, content, title)

    return json_response()


@page_router.post('/flow/page/submit/click', summary='页面提交点击')
@api_common(doc_replace=(('{0}', Config.ENV_DOC_FIX),))
@exec_duration(add_return=True)
async def do_page_submit_click(request: Request,
                               flow_record_id: int = Body(..., title='服务记录id'),
                               submit_list: list[SubmitInfo] = Body('', title='提交信息列表'),
                               session=None):
    """
    **desc**: 页面提交点击

    **url**: http(s)://{0}.udicaria.com/u/flow/page/submit/click

    **method**: POST

    **params**:

        <body>:
            flow_record_id: 服务记录id
            submit_list: [
                {
                    flow_page_id: 服务页面id
                    submit: 组件提交的信息
                }
            ] # 提交信息列表

    **return**:json数据结构::

        {
            code: 0(成功)/非0(失败)
            message: 成功返回success, 否则返回error信息
            data:
            exec_time: 接口后端处理时长
        }
    """
    await RecordService.do_page_submit_click(session, flow_record_id, submit_list)

    return json_response()
